package dao;
import domin.Actor;
import com.alibaba.fastjson.JSON;
import domin.Users;
import lombok.extern.slf4j.Slf4j;
import service.ActorService;
import util.CommonDao;
import util.Condition;
import util.JdbcHelper;
import util.Pagination;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashSet;
import java.util.TreeSet;

@Slf4j public final class UsersDao {
    private static UsersDao usersDao = new UsersDao();
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    private UsersDao() {
    }
    public static UsersDao getInstance() {
        return usersDao;
    }
    public Collection<Users> findAll(Connection connection, Collection<Condition> condition, Pagination pagination) throws SQLException {
        Collection<Users> users = new TreeSet<Users>();
        int totalNum = CommonDao.getInstance().count(connection,"Users");
        String sql_select_all = "SELECT * FROM users ";
        if (condition != null){
            sql_select_all += Condition.toWhereClause(JSON.toJSONString(condition));
            log.trace(sql_select_all);
        }
        if (pagination != null){
            sql_select_all += pagination.toLimitClause(totalNum);
            log.trace(sql_select_all);
        }
        this.preparedStatement = connection.prepareStatement(sql_select_all);
        this.resultSet = preparedStatement.executeQuery();
        while (this.resultSet.next()){
            int id = resultSet.getInt("id");
            String username = resultSet.getString("username");
            String password = resultSet.getString("password");
            int actor_id = resultSet.getInt("actor_id");
            Actor actor = ActorDao.getInstance().find(connection,actor_id);
            Users foundUsers = new Users(id,username,password,actor);
            users.add(foundUsers);
        }
        JdbcHelper.close(this.resultSet,this.preparedStatement);
        return users;
    }

    public Users find(Connection connection, Integer id) throws SQLException {
        Users foundUsers = new Users();
        this.preparedStatement = connection.prepareStatement("select * from users where id=" +id);
        this.resultSet = this.preparedStatement.executeQuery();
        this.resultSet.next();
        foundUsers.setId(this.resultSet.getInt("id"));
        foundUsers.setUsername(this.resultSet.getString("username"));
        foundUsers.setPassword(this.resultSet.getString("password"));
        foundUsers.setActor(ActorDao.getInstance().find(connection,this.resultSet.getInt("id")));
        JdbcHelper.close(resultSet,preparedStatement);
        return foundUsers;
    }
    public Collection<Users> getAllWithCondition(Connection connection, String s) throws SQLException{
        Collection<Users> userss = new HashSet<Users>();
        String value = "%" + s + "%";
        value=" \"" + value + "\"";
        PreparedStatement preparedStatement = connection.prepareStatement("" +
                "select * from Users where " +
                "username like " + value);
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            Users users = null;
            Integer id = resultSet.getInt("id");
            String username = resultSet.getString("username");
            String password = resultSet.getString("password");
            Actor actor = ActorDao.getInstance().find(connection,this.resultSet.getInt("id"));
            users = new Users(id,username,password,actor);
            userss.add(users);
        }
        JdbcHelper.close(null,preparedStatement);
        return userss;
    }

    public boolean update(Connection connection, Users users) throws SQLException {
        this.preparedStatement = connection.prepareStatement("update Users set username = ? ,password=? , actor_id=? where id=?");
        this.preparedStatement.setString(1, users.getUsername());
        this.preparedStatement.setString(2, users.getPassword());
        this.preparedStatement.setInt(3, users.getActor().getId());
        this.preparedStatement.setInt(4, users.getId());
        int rowAffected = this.preparedStatement.executeUpdate();
        JdbcHelper.close(null,preparedStatement);
        return rowAffected > 0;
    }

    public boolean add(Connection connection, Users users) throws SQLException {
        this.preparedStatement = connection.prepareStatement("INSERT INTO Users (username,password,actor_id) VALUES (?,?,?)");
        preparedStatement.setString(1, users.getUsername());
        preparedStatement.setString(2, users.getPassword());
        preparedStatement.setInt(3, users.getActor().getId());
        int rowAffected = this.preparedStatement.executeUpdate();
        JdbcHelper.close(null,preparedStatement);
        return rowAffected>0;
    }

    public boolean delete(Connection connection,Integer id) throws SQLException {
        this.preparedStatement = connection.prepareStatement("delete from Users where id=" + id);
        int rowAffected = preparedStatement.executeUpdate();
        JdbcHelper.close(null,preparedStatement);
        return rowAffected>0;
    }
    public Actor login(Connection connection, Users user) throws SQLException {
        Actor currentActor = null;
        String sql_login = "SELECT * FROM users WHERE username =? and password=?";
        PreparedStatement pstmt_login =
                connection.prepareStatement(sql_login);
        pstmt_login.setString(1, user.getUsername());
        pstmt_login.setString(2, user.getPassword());
        ResultSet resultSet_login = pstmt_login.executeQuery();
        if (resultSet_login.next()) {
            int actor_id = resultSet_login.getInt("actor_id");
            currentActor = ActorService.getInstance().find(actor_id);
        }
        return currentActor;
    }
}
